package com.payroll.framework;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.log4j.Category;

import com.payroll.framework.util.PayrollErrorConstants;
/**
 * A factory class that provides java.sql Connections.
 * @author Unknown
 */
 /* S Popovic Converted/modified for new struts framework 11/15/2001 */
public class ConnectionManager {


	private Context ctx;
	private static ConnectionManager instance;
	private HashMap dataSources = new HashMap();
	private static String connectionPoolType = "WebSphere";

	/**
* The default constructor that loads all known data source alias' from the
* AMSResourceBundle
* @author Unknown
*/
private ConnectionManager() {
	Category cat = Category.getInstance(this.getClass().getName() + ".init");


	/* Read in the datasource */
	String m_ds = Foundation.getProperty("jndiDataSource");
	String m_search_ds = Foundation.getProperty("jndiSearchDataSource");
	String m_udb_ds = Foundation.getProperty("jndiUdbDataSource");
	try {
		AliasInfo ainfo = new AliasInfo();
		ainfo.setDataSource(m_ds);
		dataSources.put(PayrollFrameworkConstants.DEFAULT_DATASOURCE,ainfo);
		AliasInfo udbAinfo = new AliasInfo();
		udbAinfo.setDataSource(m_udb_ds);
		dataSources.put(PayrollFrameworkConstants.DEFAULT_UDB_DATASOURCE,udbAinfo);
		AliasInfo searchAinfo = new AliasInfo();
		searchAinfo.setDataSource(m_search_ds);
		dataSources.put(PayrollFrameworkConstants.DEFAULT_SEARCH_DATASOURCE,searchAinfo);


		/* Used to support multiple datasources
		// Data source parser.
		RE dsParser = new RE("( *= *\\{)|( *\\} *, *)|(\\}) *");

		// Alias info parser.
		RE aiParser = new RE(" *, *");

		String[] tokens = dsParser.split(dsList);
		for (int j = 0; j < tokens.length; j += 2) {
			String alias = tokens[j];
			String info = tokens[j + 1];
			String[] infoItems = aiParser.split(info);
			if (infoItems.length == 3) {
				AliasInfo ainfo = new AliasInfo();
				ainfo.setAlias(alias);
				ainfo.setDataSource(infoItems[0].trim());
				ainfo.setUserId(Foundation.decrypt(infoItems[1].trim()));
				ainfo.setPassword(Foundation.decrypt(infoItems[2].trim()));
				dataSources.put(alias, ainfo);
			}
		} */
		printConnectionInfo(PayrollFrameworkConstants.DEFAULT_DATASOURCE);
	} catch (Exception e) {
		e.printStackTrace();
	}
}
/**
* Returns a connection to a datasource.  If the datasource is
* invalid, an SQLException is thrown.
* @return A java.sql connection to the database.
* @param p_dataSource The data source alias as defined in the PayrollResourceBundle.
* @author S Popovic
*/
public static java.sql.Connection getConnection(String p_dataSource, BigDecimal p_priority) throws PayrollFoundationException,SQLException{

	/*if(Foundation.getProperty("connectionPoolType").equals("WebSphere")) {
		return getFactory().getWebSphereConnection(p_dataSource.trim());
	}
	else if (Foundation.getProperty("connectionPoolType").equals("WebLogic")){
		return getFactory().getWebLogicConnection(p_dataSource.trim(),p_priority);
	}
	else {*/
		return getFactory().getStrutsConnection(Foundation.getServletContext());
	//}
}
/**
* Returns a connection to a datasource.  If the datasource is
* invalid, an SQLexception is thrown.
* @param dataSource The datasource requested.
* @return java.sql.Connection
* @author Unknown
*/
/* S Popovic - modified for new framework 12/15/2001 */
public boolean dbUserExists(String p_dataSource, String p_user, String p_password)
throws PayrollFoundationException,SQLException {
	Category cat = Category.getInstance("com.ams.framework.ConnectionManager.getUserConnection");
	if (dataSources.containsKey(p_dataSource)) {

		AliasInfo ainfo = (AliasInfo) dataSources.get(p_dataSource);
		try {
			DataSource ds = (DataSource) ctx.lookup("jdbc/" + ainfo.getDataSource());
			Connection m_connection = ds.getConnection(p_user,p_password);
			if(m_connection != null) {
				m_connection.close();
				return true;
			}
			else {
				return false;
			}

		} catch (NamingException e) {
			String[] m_subs = {ainfo.getDataSource(),ainfo.getAlias()};
			cat.error("Datasource "+ainfo.getDataSource()+" with alias "+ainfo.getAlias()+" was not found in Websphere.");
			throw new PayrollFoundationException
			("ConnectionManager::getDSConnection",PayrollErrorConstants.DatasourceNotFound,m_subs);
		}


	} else {
		StringBuffer dsList = new StringBuffer();
		Iterator i = dataSources.keySet().iterator();
		while (i.hasNext()) {
			dsList.append(i.next() + ", ");
		}
		cat.error("An invalid data source, "
				+ p_dataSource
				+ " was specified.  Valid datasources are: "
				+ dsList.toString());

		throw new PayrollFoundationException
		("ConnectionManager::getDSConnection",PayrollErrorConstants.InvalidDatasource,p_dataSource);

	}
}
/**
* Returns the singleton instance of the Connection Manager.
* @return com.ams.framework.ConnectionManager The AMS connection Manager.
* @author S Popovic - from previous frameworks.
*/
public static ConnectionManager getFactory() {
	if (instance == null) {
		instance = new ConnectionManager();
	}
	return instance;
}

/**
 * Sets the singleton Connection Manager instance to null.  The next time the
 * Connection Manager is needed, it will be re-initialized
 * @author S Popovic
 */
public static void refresh() {

	instance = null;

	}

private void printConnectionInfo(String p_alias) {
	Category cat = Category.getInstance("ConnectionManager.printConnectionInfo");
	AliasInfo m_ai = new AliasInfo();
	m_ai = (AliasInfo) dataSources.get(p_alias);

}

public String getDatabaseName(String p_Alias) {
	AliasInfo m_ai = new AliasInfo();
	m_ai = (AliasInfo) dataSources.get(p_Alias);
	return m_ai.getDataSource();

}

/**
 * Insert the method's description here.
 * Creation date: (1/8/2002 11:37:59 AM)
 * @return javax.sql.DataSource
 */
private Connection getStrutsConnection(javax.servlet.ServletContext p_ServletContext) throws
PayrollFoundationException, SQLException{
	Category cat = Category.getInstance("ConnectionManager.getStrutsConnection");

	Connection m_Connection = null;
	String url = "jdbc:mysql://localhost:3306/";
	  String dbName = "test";
	  String driverName = "org.gjt.mm.mysql.Driver";
	  String userName = "root";
	  String password = "root";
	  try {
		Class.forName(driverName).newInstance();
	} catch (InstantiationException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (IllegalAccessException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	  m_Connection=DriverManager.getConnection(url+dbName, userName,password);
	 // stmt=con.createStatement();
	//DataSource m_DS = (DataSource) p_ServletContext.getAttribute(PayrollFrameworkConstants.STRUTS_DATASOURCE);
	//m_Connection = m_DS.getConnection();

	if(m_Connection == null) {

		throw new PayrollFoundationException(cat.getName(),"Unable to get connection from Struts Datasource");
	}
	else {
		m_Connection.setAutoCommit(false);
	}

	return m_Connection;
}

private java.sql.Connection getWebSphereConnection(String dataSource)
	throws PayrollFoundationException, SQLException {

	Category cat = Category.getInstance("com.ams.framework.ConnectionManager.getDSConnection");
	if (dataSources.containsKey(dataSource)) {

		AliasInfo ainfo = (AliasInfo) dataSources.get(dataSource);
		try {
			// If the static variables are null then get the decrypted value and save it for further use
			/*if (auserID == null && apassword == null){
				auserID = Foundation.decrypt(ainfo.getUserId());
				apassword = Foundation.decrypt(ainfo.getPassword());
			} */

			DataSource ds = (DataSource) ctx.lookup("jdbc/" + ainfo.getDataSource());
			Connection m_connection =
			ds.getConnection(ainfo.getUserId(),ainfo.getPassword());
			m_connection.setAutoCommit(false);
			return m_connection;
		} catch (NamingException e) {
			String[] m_subs = {ainfo.getDataSource(),ainfo.getAlias()};
			cat.error("Datasource "+ainfo.getDataSource()+" with alias "+ainfo.getAlias()+" was not found in Websphere.");
			throw new PayrollFoundationException
			("ConnectionManager::getDSConnection",PayrollErrorConstants.DatasourceNotFound,m_subs);
		}

	} else {
		StringBuffer dsList = new StringBuffer();
		Iterator i = dataSources.keySet().iterator();
		while (i.hasNext()) {
			dsList.append(i.next() + ", ");
		}
		cat.error("An invalid data source, "
				+ dataSource
				+ " was specified.  Valid datasources are: "
				+ dsList.toString());

		throw new PayrollFoundationException
		("ConnectionManager::getDSConnection",PayrollErrorConstants.InvalidDatasource,dataSource);

	}
}
private java.sql.Connection getWebLogicConnection(String dataSource, BigDecimal p_priority)
	throws PayrollFoundationException, SQLException {

	Category cat = Category.getInstance("com.ams.framework.ConnectionManager.getWebLogicConnection");
	if (dataSources.containsKey(dataSource)) {
		AliasInfo ainfo = null;
		try {
			// Get defalult Connection Information
			if("false".equalsIgnoreCase(Foundation.getProperty("enableMultiPool")))  {
				ainfo = (AliasInfo) dataSources.get(PayrollFrameworkConstants.DEFAULT_DATASOURCE);
			} else {
				ainfo = (AliasInfo) dataSources.get(dataSource);
			}

			DataSource ds = (DataSource) ctx.lookup("jdbc/" + ainfo.getDataSource());
			Connection m_connection = ds.getConnection();
			m_connection.setAutoCommit(false);

//			if ("true".equalsIgnoreCase(Foundation.getProperty("enableWLM"))) {
//				if (SacwisConstants.CONNECTION_PRIORITY_HIGH.equals(p_priority)) {
//					((DB2Connection)((PoolConnection)m_connection).getVendorConnection()).setDB2ClientAccountingInformation(SacwisConstants.CONNECTION_PRIORITY_HIGH_STRING);
//				} else if (SacwisConstants.CONNECTION_PRIORITY_HIGH.equals(p_priority)) {
//					((DB2Connection)((PoolConnection)m_connection).getVendorConnection()).setDB2ClientAccountingInformation(SacwisConstants.CONNECTION_PRIORITY_LOW_STRING);
//				}
//				m_connection.prepareStatement("SELECT * FROM SYSIBM.SYSDUMMY1 WHERE 0 = 1").executeQuery();
//				m_connection.commit();
//			}

			if("on".equalsIgnoreCase(Foundation.getProperty("developerMode")) || cat.isDebugEnabled()) {
				//return new LogConnection(m_connection);
				return null;
			}
			else {
				return m_connection;
			}
		} catch (NamingException e) {
			String[] m_subs = {ainfo.getDataSource(),ainfo.getAlias()};
			cat.error("Datasource "+ainfo.getDataSource()+" with alias "+dataSource+" was not found in WebLogic.");
			throw new PayrollFoundationException
			("ConnectionManager::getWebLogicConnection",PayrollErrorConstants.DatasourceNotFound,m_subs);
		}
	} else {
		StringBuffer dsList = new StringBuffer();
		Iterator i = dataSources.keySet().iterator();
		while (i.hasNext()) {
			dsList.append(i.next() + ", ");
		}
		cat.error("An invalid data source, "
				+ dataSource
				+ " was specified.  Valid datasources are: "
				+ dsList.toString());

		throw new PayrollFoundationException
		("ConnectionManager::getWebLogicConnection",PayrollErrorConstants.InvalidDatasource,dataSource);

	}
}

}
